package connections;

import java.util.List;
import java.util.Set;

import serverDB.Box;
import serverDB.Client;
import serverDB.Computer;
import serverDB.ConnectToDataBase;
import serverDB.File;
import serverManger.Server;
import message.*;

/**
 * deal with the operation that need to be done after receive massage
 * @author ran
 *
 */
public class MessageHandler {
	private Server server = Server.getServerInst();
	private Client user=null;
	private Computer comp = null;
	/**
	 * this method parsing the message and take the right operation
	 * @param message - the message to parse
	 * @return
	 */
	public Message interpretMessage(Message message){
		Message responseMessage=null;
		switch(message.getType()){
		case START_COMUNICATION:
			responseMessage = startComunicationMC(message);
			break;
		case FILE_WAS_CHANGED:
			responseMessage = fileWasChangedMC(message);
			break;
		case TRANSFER_FILE:
			responseMessage = transferFileMC(message);
			break;
		case SEND_FILE:
			responseMessage = sendFileMC(message);
			break;
		case NEW_CLIENT:
			responseMessage= newClientMC(message);
			break;
		case START_SYNC:
			responseMessage = startSyncMC();
			break;
		case STOP_SYNC:
			responseMessage = stopSyncMC();
			break;
		case NEW_BOX:
			responseMessage = newBoxMC(message);
			break;
		case SHARE_BOX:
			responseMessage = shareBoxMC(message);
			break;
		case INFO:
			responseMessage = getInfoMC(message);
			break;
		
		}
	System.out.println(message.getType());
	return responseMessage;
	}
	/*
	 * this method handle the case of "INFO" message was received
	 */
	private Message getInfoMC(Message message) {
		System.out.println("info message");
		return server.getClientInfo(user);
	}
	/*
	 * this method handle the case of "SHARE_BOX" message was received
	 */
	private Message shareBoxMC(Message message) {
		ShareBox shareBox= (ShareBox)message;
		server.shareBox(user,shareBox.getBoxName(),shareBox.getEmails());
		return new StopComunication();
	}
	/*
	 * this method handle the case of "NEW_BOX" message was received
	 */
	private Message newBoxMC(Message message) {
		NewBox newBox= (NewBox)message;
		server.newBox(newBox.getBoxName(), user, comp);
		return new StopComunication();
	}
	/*
	 * this method handle the case of "STOP_SYNC" message was received
	 */
	private Message stopSyncMC() {
		server.stopSync(comp);
		return new StopSync();
	}
	/*
	 * this method handle the case of "START_SYNC" message was received
	 */
	private Message startSyncMC() {
		System.out.println("YHAAAAAAA");
		// get the next messge if there is one
		Message message = server.getNextMessage(comp);
		System.out.println("Message: "+message);
		if(message!=null)
			return message;
		return new StopComunication();
	}
	/*
	 * this method handle the case of "NEW_CLIENT" message was received
	 */
	private Message newClientMC(Message message) {
		NewClient newClient= (NewClient)message;
		// create the new client 
		Message m=server.addNewClient(newClient.getUsername(),newClient.getPass(),newClient.getEmail()
				 			,newClient.getComputerName(),newClient.getPath(),newClient.getBoxName());
		//set the client object 
		List<Client> clients = ConnectToDataBase.getInst().getClient2("from Client where user_name= '"+newClient.getUsername()+"'");
		if(!clients.isEmpty())
			user = clients.get(0);
		// set the computer Object
		Set<Computer> comps = user.getComputers();
		for(Computer c : comps){
			if(c.getComputerName().compareTo(newClient.getComputerName())==0){
				comp=c;
				break;
			}
		}
		
		return m;
	}
	/*
	 * this method handle the case of "START_COMUNICATION" message was received
	 */
	private Message startComunicationMC(Message message) {
		StartComunication startMessage=(StartComunication)message;
		// if the user is register for the first time
		if(startMessage.getUserName().compareTo("client")==0 && startMessage.getPass().compareTo("client")==0)
			return new StartComunication("server", "server","server");
		// check if the user is already exist
		user=server.isClientExist(startMessage.getUserName(),startMessage.getPass());
		Set<Computer> computers = user.getComputers();
		System.out.println("computers list size: "+computers.size());
		// set the computer object
		for(Computer c : computers){
			System.out.println("computer : "+ c.getComputerName());
			if(c.getComputerName().compareTo(startMessage.getComputerName())==0){
				comp=c;
				break;
			}
		}
		// set that the client is connected
		server.setClientIsConnected(comp.getComputerId(), true);
		// return message
		if(user!=null)
			return new StartComunication("server", "server","server");
		return new StopComunication();
	}
	/*
	 * this method handle the case of "TRANSFER_FILE" message was received
	 */
	private Message transferFileMC(Message message) {
		TransferFile transferFile = (TransferFile)message;
		// create the file on the server computer
		server.createFile(transferFile.getFileName(), transferFile.getByteArray(),transferFile.getBoxName(),user,transferFile.getCheckSum(),transferFile.getFileWasChanged().getModDate(),transferFile.getFileWasChanged().getAllTages());
		// update other computer that the file was transfered
		server.updateOtherCompMess(user,comp,transferFile.getFileWasChanged(),transferFile.getFileWasChanged().getBoxName());
		return new StopComunication();
	}
	/*
	 * this method handle the case of "FILE_WAS_CHANGED" message was received
	 */
	private Message fileWasChangedMC(Message message){
		FileWasChanged fileWasChanged=(FileWasChanged)message;
		System.out.println(fileWasChanged.getFileName()+" "+ fileWasChanged.getBoxName());
		if(server.fileWasChanged(user,fileWasChanged.getFileName(), fileWasChanged.getCheckSum(), fileWasChanged.getFileSize(),fileWasChanged.getBoxName(),comp,fileWasChanged)){
			System.out.println(fileWasChanged.getFileName()+" "+ fileWasChanged.getBoxName());
			return new SendFile(fileWasChanged.getBoxName()+"\\"+fileWasChanged.getFileName(),fileWasChanged.getFileName(),fileWasChanged.getCheckSum(),fileWasChanged);
		}
		else{
			System.out.println("file already exist!!!");
			return new StopComunication();
		}
			
	}
	/*
	 * this method handle the case of "SEND_FILE" message was received
	 */
	private Message sendFileMC(Message message){
		SendFile sendFile = (SendFile)message;
		Set<Box> boxes = user.getBoxes();
		Box theBox=null;
		// get the box object
		for(Box b : boxes){
			if(b.getBoxName().equals(sendFile.getFileWasChanged().getBoxName())){
				theBox=b;
				break;
			}
		}
		// get the files from the box
		Set<File> files = theBox.getFiles();
		File theFile=null;
		for(File f : files){
			if(f.getFileName().equals(sendFile.getFileName())){
				theFile=f;
				break;
			}
		}
		return new TransferFile(sendFile.getFileName(), server.getFileBytes(theFile.getFileLocation()), theBox.getBoxName(), 1, sendFile.getFileWasChanged());
	}
	/**
	 * return the computer Object
	 * @return the computer Object
	 */
	public Computer getComp() {
		return comp;
	}
}